using System.Collections.Generic;
using UnityEngine;
using Cysharp.Threading.Tasks;


public enum UILayer{
    Low = 0,
    Normal = 1,
    Operate = 2,
    Effect = 3,
    Notice = 4,
}

public class UIMgr : Singleton<UIMgr>
{
    GameObject _uiRoot;
    RectTransform[] _layers;
    public GameObject UIRoot
    {
        get
        {
            if (_uiRoot == null)
            {
                // _uiRoot = GameObject.Find("Canvas");
                LoadCanvas();
            }
            return _uiRoot;
        }
    }

    //UI打开的字典
    Dictionary<UINAMES, UIBase> _uiDic = new Dictionary<UINAMES, UIBase>();
    //UI缓存字典
    Dictionary<UINAMES, UIBase> _uiCacheDic = new Dictionary<UINAMES, UIBase>();

    int _cacheTime = 10;
    bool autoClearCache = false;
    bool AutoClearCache {
        get
        {
            return autoClearCache;
        }
        set
        {
            autoClearCache = value;
            if (autoClearCache)
            {
                ClearCacheUIAsync();
            }
        }
    }

    async void LoadCanvas()
    {
        GameObject obj = await LoadMgr.Instance.Instantiate("Assets/Prefab/Canvas.prefab");
        obj.name = "UIRoot";
        _uiRoot = obj;
        Object.DontDestroyOnLoad(_uiRoot);
        InitUIRoot();
    }
    public override void Init()
    {
        base.Init();
        var ins = UIRoot;
    }

    void InitUIRoot()
    {
        var layers = System.Enum.GetValues(typeof(UILayer));
        _layers = new RectTransform[layers.Length];
        //遍历UILayer枚举
        foreach (UILayer layer in System.Enum.GetValues(typeof(UILayer))){
            //在UIRoot下查找对应的层级
            UIRoot.transform.Find(layer.ToString());
            _layers[(int)layer] = UIRoot.transform.Find(layer.ToString()).GetComponent<RectTransform>();
        }
        AutoClearCache = true;
    }

    //通过UI打开界面
    public async UniTask<UIBase> OpenUI(UINAMES uiName)
    {
        UIBase ui = await LoadOpenUI(uiName);
        if(ui == null)
        {
            Debug.LogError("UIName 不能为None");
            return null;
        }
        ui.Open();
        return ui;
    }

    //通过UI关闭界面
    public void CloseUI(UINAMES uiName)
    {
        UIBase ui = null;
        if (_uiDic.TryGetValue(uiName, out ui))
        {
            ui.Close();
            _uiDic.Remove(uiName);
            _uiCacheDic.Add(uiName, ui);
        }
    }

    //查找UI
    public UIBase FindUI(UINAMES uiName)
    {
        UIBase ui = null;
        if (_uiDic.TryGetValue(uiName, out ui))
        {
            return ui;
        }

        if (_uiCacheDic.TryGetValue(uiName, out ui))
        {
            _uiDic.Add(uiName, ui);
            _uiCacheDic.Remove(uiName);
            return ui;
        }
        return null;
    }

    //LoadUI
    async UniTask<UIBase> LoadUI(UIItemCfg cfg)
    {
        GameObject uiGo = await LoadMgr.Instance.Instantiate(cfg.Prefab);
        uiGo.name = cfg.Name.ToString();
        var uiRT = uiGo.GetComponent<RectTransform>();
        uiRT.SetParent(_layers[(int)cfg.Layer]);
        uiRT.localScale = Vector3.one;
        uiRT.localPosition = Vector3.zero;
        if(cfg.FullScreen)
            SetFullScreen(uiRT);

        UIBase ui = uiGo.GetComponent<UIBase>();
        return ui;
    }

    //load open UI 
    public async UniTask<UIBase> LoadOpenUI(UINAMES uiName)
    {
        if(uiName == UINAMES.NONE)
        {
            Debug.LogError("UIName 不能为None");
            return null;
        }
        UIItemCfg cfg = UIConfigMgr.Instance.GetUIItem(uiName);
        // var cfg = new UIItem();
        if(cfg == null)
        {
            Debug.LogError("UIConfig中没有配置" + uiName);
            return null;
        }
        UIBase ui = FindUI(uiName);
        //如果都没有，加载
        if(ui == null)
        {
            ui = await LoadUI(cfg);
            _uiDic.Add(uiName, ui);
        }
        return ui;
    }

    // unitask 定时循环清理缓存UI
    public async void ClearCacheUIAsync()
    {
        int time = _cacheTime * 1000;
        while (AutoClearCache)
        {
            await UniTask.Delay(time);
            ClearCacheUI();
        }
    }


    //定时清理缓存UI
    public void ClearCacheUI()
    {
        foreach (var ui in _uiCacheDic.Values)
        {
            GameObject.Destroy(ui.gameObject);
        }
        _uiCacheDic.Clear();

        Debug.Log("清理缓存UI");
    }

    //通过Key获取打开的UI
    public UIBase GetOpenUI(UINAMES uiName)
    {
        UIBase ui = null;
        if (_uiDic.TryGetValue(uiName, out ui))
        {
            return ui;
        }
        return null;
    }

    //通过Key查看UI是否打开
    public bool IsOpenUI(UINAMES uiName)
    {
        UIBase ui = null;
        if (_uiDic.TryGetValue(uiName, out ui))
        {
            return true;
        }
        return false;
    }

    public override void Clean()
    {
        base.Clean();
        AutoClearCache = false;
        foreach (var ui in _uiDic.Values)
        {
            GameObject.Destroy(ui.gameObject);
        }

        foreach (var ui in _uiCacheDic.Values)
        {
            GameObject.Destroy(ui.gameObject);
        }

        _uiDic.Clear();
        _uiCacheDic.Clear();

        GameObject.Destroy(_uiRoot);
    }

    //rectTransform 设置全屏
    public void SetFullScreen(RectTransform rectTransform)
    {
        rectTransform.anchorMin = Vector2.zero;
        rectTransform.anchorMax = Vector2.one;
        rectTransform.offsetMin = Vector2.zero;
        rectTransform.offsetMax = Vector2.zero;
    }


//--------------------------------------------------

    //通过UI打开界面 传模板数据
    public async UniTask<UIBase> OpenUI<T>(UINAMES uiName, T data)
    {
        UIBase ui = await LoadOpenUI(uiName);
        if(ui == null)
        {
            Debug.LogError("UIName 不能为None");
            return null;
        }
        ui.Open(data);
        return ui;
    }

    //通过UI打开界面 传模板数据
    public async UniTask<UIBase> OpenUI<T,T1>(UINAMES uiName, T data,T1 data1)
    {
        UIBase ui = await LoadOpenUI(uiName);
        if(ui == null)
        {
            Debug.LogError("UIName 不能为None");
            return null;
        }
        ui.Open(data,data1);
        return ui;
    }

    //通过UI打开界面 传模板数据
    public async UniTask<UIBase> OpenUI<T,T1,T2>(UINAMES uiName, T data,T1 data1,T2 data2)
    {
        UIBase ui = await LoadOpenUI(uiName);
        if(ui == null)
        {
            Debug.LogError("UIName 不能为None");
            return null;
        }
        ui.Open(data,data1,data2);
        return ui;
    }

    //通过UI打开界面 传模板数据
    public async UniTask<UIBase> OpenUI<T,T1,T2,T3>(UINAMES uiName, T data,T1 data1,T2 data2,T3 data3)
    {
        UIBase ui = await LoadOpenUI(uiName);
        if(ui == null)
        {
            Debug.LogError("UIName 不能为None");
            return null;
        }
        ui.Open(data,data1,data2,data3);
        return ui;
    }

}